﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EasyStep.Business;
using EasyStep.Business.Interfaces;
using EasyStep.Attributes;
using EasyStep.Data.Entities;
using EasyStep.TestEditor.Test;

namespace EasyStep.WinForms.Controls
{
    public partial class TestStepEditorControl : UserControl
    {

        public Color CorrectTestStepData = System.Drawing.SystemColors.ButtonFace;
        public Color IncorrectTestStepData = Color.LightCoral;

        private ITestDataContext DataContext { get; set; }
        public Label lblInfo;
        public TestStep Data { get; private set; }
        public bool AutoConstantGeneration
        {
            set
            {
                wzdLocator.AutoConstantGeneration = value;
                wzdData.AutoConstantGeneration = value;
            }
        }
        public event EventHandler OnAddAfterCurrent;
        public event EventHandler OnRemove;
        public event EventHandler OnFocusLeave;

        private IEnumerable<TestAction> actions;

        public TestStepEditorControl(TestStep data, IEnumerable<TestAction> testActions)
        {
            Data = data;
            actions = testActions;
            this.Enabled = false;
            InitializeComponent();
            
            wzdData.OnFocusLeave += new EventHandler(Control_LostFocus);
            wzdLocator.OnFocusLeave += new EventHandler((a, b) => ValidateTestStep());
            tmrDataRenderer.Tick += new EventHandler(tmrDataRenderer_Tick);

            tmrDataRenderer.Start();
        }



        /// <summary>
        /// in that way rendering will be much more fast then synchronously 
        /// </summary>
        void tmrDataRenderer_Tick(object sender, EventArgs e)
        {
            var frm = (ParentForm as ITestContextForm);
            if (frm == null) return;
            tmrDataRenderer.Stop(); 
            DataContext = frm.DataContext;
            wzdLocator.DataContext = DataContext;
            wzdData.DataContext = DataContext;

            if (Data.ActionId != Guid.Empty)
            {
                Data.Action = actions.Where(a => a.Id.Equals(Data.ActionId)).FirstOrDefault();
                Data.ActionId = Data.Action == null ? Guid.Empty : Data.Action.Id;
            }
            if (Data.ActionId == Guid.Empty) Data.Action = null;

            BindComboBox(CbAction, actions.Where(a => a.ParentId.Equals(Guid.Empty)), Data.Action == null ? Guid.Empty : Data.Action.ParentId);
            var cparent = CbAction.SelectedItem as TestAction;

            if (cparent != null)
                BindComboBox(CbSubAction, actions.Where(a => a.ParentId.Equals(cparent.Id)), Data.ActionId);
            Data.Action = CbSubAction.SelectedItem as TestAction;
            if (Data.Action != null)
                BindTextBoxes(Data);
            Refresh_Info(null, null);
            this.Enabled = true;
            ValidateTestStep();
        }

        private void BindComboBox(ComboBox cboxAction, IEnumerable<TestAction> dataSource, Guid selectedId, string displayMember = "Name")
        {
            if (dataSource == null) return;
            cboxAction.DisplayMember = displayMember;
            cboxAction.DataSource = dataSource.ToList();
            var selectedItem = dataSource.Where(i => i.Id.Equals(selectedId)).FirstOrDefault();
            if (selectedItem != null)
                cboxAction.SelectedItem = selectedItem;
        }
        private void Control_LostFocus(object sender, EventArgs e)
        {
            if (this.Enabled && ValidateTestStep() && OnFocusLeave != null)
            {
                OnFocusLeave(this, e);
            }
        }
        protected void BindTextBoxes(TestStep data)
        {
            this.wzdData.Visible = data.Action.RequireData;
            this.wzdData.Data = data.Data;
            this.wzdData.SetWatermark("Data");
            this.wzdLocator.Visible = data.Action.RequireLocator;
            this.wzdLocator.Data = data.Locator;
            this.wzdLocator.SetWatermark("Locator");
        }

        private void CbAction_SelectedIndexChanged(object sender, EventArgs e)
        {
            var parentId = ((TestAction)((ComboBox)sender).SelectedItem).Id;
            var subActions = actions.Where(a => a.ParentId.Equals(parentId)).ToList();
            CbSubAction.Visible = subActions.Count() > 0;
            CbSubAction.DataSource = subActions;
            Data.Action = subActions.FirstOrDefault();
            if (subActions.Any()) BindTextBoxes(Data);
        }

        private void CbSubAction_SelectedIndexChanged(object sender, EventArgs e)
        {
            Data.Action = (TestAction)((ComboBox)sender).SelectedItem;
            BindTextBoxes(Data);
        }

        private void BtnAdd_Click(object sender, EventArgs e)
        {
            if (OnAddAfterCurrent != null)
                OnAddAfterCurrent(this, e);
        }
        private void BtnRemove_Click(object sender, EventArgs e)
        {
            if (OnRemove != null)
                OnRemove(this, e);
        }

        private void Child_MouseDown(object sender, MouseEventArgs e)
        {
            OnMouseDown(e);
        }
        private void Child_MouseUp(object sender, MouseEventArgs e)
        {
            OnMouseUp(e);
        }
        private void Child_MouseMove(object sender, MouseEventArgs e)
        {
            OnMouseMove(e);
        }


        private void BtnFlat_MouseEnter(object sender, EventArgs e)
        {
            var BtnFlat = sender as Button;
            BtnFlat.FlatAppearance.BorderSize = 1;
            BtnFlat.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
        }
        private void BtnFlat_MouseLeave(object sender, EventArgs e)
        {
            var BtnFlat = sender as Button;
            BtnFlat.FlatAppearance.BorderSize = 0;
            BtnFlat.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        }


        public bool ValidateTestStep()
        {
            if (!this.Enabled) return true;
            var result = base.ValidateChildren();
            var selParentAction = (TestAction)CbAction.SelectedItem;
            var selAction = (TestAction)CbSubAction.SelectedItem;
            selAction = selAction == null ? null : actions
                .Where(a => a.Id.Equals(selAction.Id) && a.ParentId.Equals(selParentAction.Id))
                .FirstOrDefault();//here we 100% sure that action and parent action related each other
            if (selAction == null) selAction = selParentAction;
            else selAction.Parent= selParentAction;
            var curData = new TestStep()
            {
                ActionId = selAction == null ? Guid.Empty : selAction.Id,
                Action = selAction
            };
            if (curData.Action == null)
                result = false;
            else
            {
                var isDataOk = !curData.Action.RequireData ? true : wzdData.ValidateData();
                curData.Data = !curData.Action.RequireData ?null:wzdData.Data;
                var isLocatorOk = !curData.Action.RequireLocator ? true : wzdLocator.ValidateData();
                curData.Locator = !curData.Action.RequireLocator ?null:wzdLocator.Data;
                curData.Updated = DateTime.Now;
                result = result && isDataOk && isLocatorOk;
            }
            this.Data = curData;
            this.BackColor = result ? CorrectTestStepData : IncorrectTestStepData;
            return result;
        }

        private void Refresh_Info(object sender, EventArgs e)
        {
            lblInfo.Text = string.Format("{0}", this.Parent.Controls.GetChildIndex(this) + 1, this.Top);
        }





    }
}
